<template>
  <div class="Independent" @mousedown="handleMouseDown">
    <div
      class="mask"
      v-show="is_show_mask"
      :style="
        'width:' +
          mask_width +
          'left:' +
          mask_left +
          'height:' +
          mask_height +
          'top:' +
          mask_top
      "
    ></div>
    <el-table
      :row-style="tableRowStyle"
      ref="mutipleTable"
      height="100vh"
      :data="edittableData"
      tooltip-effect="dark"
      style="width: 100%"
      @selection-change="handlerSelectChange"
      border
      @row-click="handlerRowClick"
      :header-cell-style="{
        background: '#b8dbf7',
        padding: '0px',
        color: '#000000',
        fontWeight: 'normal',
      }"
      size="mini"
      @row-contextmenu="openMenu"
    >
      <el-table-column
        type="selection"
        width="55"
        v-if="false"
      ></el-table-column>
      <el-table-column type="index">
        <template slot-scope="scope">
          <span class="index">{{ scope.$index }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="id" label="id" width="75" sortable>
        <template slot-scope="scope">{{ scope.row.id }}</template>
      </el-table-column>
      <el-table-column prop="model" label="型号" sortable>
        <template slot-scope="scope">
          <a href="http://localhost:8080/#/home">{{ scope.row.model }}</a>
        </template>
      </el-table-column>
      <el-table-column prop="color" label="颜色"></el-table-column>
      <el-table-column prop="size" label="尺寸"></el-table-column>
      <el-table-column prop="num" label="现库存"></el-table-column>
    </el-table>

    <ul
      v-show="visible"
      :style="{ left: left + 'px', top: top + 'px' }"
      class="contextmenu"
    >
      <li @click="clearSelection()">取消选择</li>
      <li>取消</li>
    </ul>
  </div>
</template>

<script>
export default {
  props: {},
  data() {
    return {
      is_show_mask: true,
      checkList: [],
      start_x: 0,
      start_y: 0,
      end_x: 0,
      end_y: 0,

      visible: false,
      top: 0,
      left: 0,

      edittableData: [],
      selectData: [],
      pin: false,
      origin: -1, // 这里给一个变量作为起点
      map: {},
      numbersHistory: [],
      currentRow: {},
      clickFlag: false,
    };
  },
  computed: {
    mask_width() {
      return Math.abs(this.end_x - this.start_x) + "px;";
    },
    mask_left() {
      return Math.min(this.start_x, this.end_x) + "px;";
    },
    mask_height() {
      return Math.abs(this.end_y - this.start_y) + "px;";
    },
    mask_top() {
      return Math.min(this.start_y, this.end_y) + "px;";
    },
  },
  watch: {
    visible(value) {
      if (value) {
        document.body.addEventListener("click", this.closeMenu);
      } else {
        document.body.removeEventListener("click", this.closeMenu);
      }
    },
  },
  created() {
    this.map = new Map();
    for (let i = 0; i < 300; i++) {
      let data = {
        id: i,
        color: "white",
        size: 20,
        model: "n20" + i,
        num: 20 + i,
      };
      data.checked = false;
      data._index = i;
      this.edittableData.push(data);
      this.map.set(i, data);
    }
  },
  mounted() {},
  methods: {
    handleMouseDown(event) {
      if (event.button == 0) {
        this.start_x = event.clientX;
        this.start_y = event.clientY;
        this.end_x = event.clientX;
        this.end_y = event.clientY;
        document.body.addEventListener("mousemove", this.handleMouseMove);
        document.body.addEventListener("mouseup", this.handleMouseUp);
      }
    },
    handleMouseMove(event) {
      this.end_x = event.clientX;
      this.end_y = event.clientY;
      this.is_show_mask = true;
    },
    handleMouseUp() {
      document.body.removeEventListener("mousemove", this.handleMouseMove);
      document.body.removeEventListener("mouseup", this.handleMouseUp);
      this.is_show_mask = false;
      this.handleDomSelect();
    },
    handleDomSelect() {
      let trs = document.querySelectorAll("tr");
      let mask = document.querySelector(".mask");
      this.checkList = [];
      trs.forEach((item) => {
        if (this.collide(item, mask)) {
          let indexDom = item.querySelector(".index");
          if (indexDom) {
            let index = indexDom.innerHTML;
            this.setRowSelection(this.edittableData[index]);
          }
        }
      });
    },
    setRowSelection(row) {
      this.$refs.mutipleTable.toggleRowSelection(row, true);
      row.checked = true;
    },
    collide(rect1, rect2) {
      let rect1Object = rect1.getBoundingClientRect();
      rect1.x = rect1Object.left;
      rect1.y = rect1Object.top;
      rect1.width = rect1.offsetWidth;
      rect1.height = rect1.offsetHeight;

      let rect2Object = rect2.getBoundingClientRect();
      rect2.x = rect2Object.left;
      rect2.y = rect2Object.top;
      rect2.width = rect2.offsetWidth;
      rect2.height = rect2.offsetHeight;
      const maxX = Math.max(rect1.x + rect1.width, rect2.x + rect2.width);
      const maxY = Math.max(rect1.y + rect1.height, rect2.y + rect2.height);
      const minX = Math.min(rect1.x, rect2.x);
      const minY = Math.min(rect1.y, rect2.y);
      if (
        maxX - minX <= rect1.width + rect2.width &&
        maxY - minY <= rect1.height + rect2.height
      ) {
        return true;
      } else {
        return false;
      }
    },
    clearSelection() {
      this.$refs.mutipleTable.clearSelection();
      this.edittableData.forEach((item) => {
        item.checked = false;
      });
    },
    openMenu(row, column, e) {
      e.preventDefault();
      if (e.target.getAttribute("class") != "cell") {
        return;
      }
      this.changCellClass(e.target);
      this.currentRow = row;
      const menuMinWidth = 105;
      const offsetLeft = this.$el.getBoundingClientRect().left; // container margin left
      const offsetWidth = this.$el.offsetWidth; // container width
      const maxLeft = offsetWidth - menuMinWidth; // left boundary
      const left = e.clientX - offsetLeft; // 15: margin right

      if (left > maxLeft) {
        this.left = maxLeft;
      } else {
        this.left = left;
      }

      this.top = e.clientY; // fix 位置bug
      this.visible = true;
    },
    changCellClass(cell) {
      let cells = document.querySelectorAll(".cell.red-cell");
      if (cells) {
        cells.forEach((item) => item.setAttribute("class", "cell"));
      }
      if (cell) {
        cell.setAttribute("class", "cell red-cell");
      }
    },
    closeMenu() {
      this.visible = false;
      this.changCellClass();
    },
    handlerSelectChange(e) {
      this.selectData = e;
    },
    shiftHandlerSelection(row) {
      const data = this.$refs.mutipleTable.tableData; // 获取所以数据
      const origin = this.origin; // 起点数 从-1开始
      let endIdx = row._index; // 终点数
      // 按住
      const sum = Math.abs(origin - endIdx) + 1; // 这里记录终点
      const min = Math.min(origin, endIdx); // 这里记录起点
      let i = 0;
      while (i < sum) {
        const index = min + i;
        this.setRowSelection(data[index]);
        i++;
      }
    },
    getIndexByRow(row) {
      this.origin = row._index;
    },
    handlerRowClick(row, col, e) {
      let ctrlFlag = e.ctrlKey;
      let shiftFlag = e.shiftKey;
      if (!ctrlFlag && !shiftFlag) {
        this.clearSelection();
        this.setRowSelection(row);
        this.getIndexByRow(row);
      } else if (!ctrlFlag && shiftFlag) {
        this.shiftHandlerSelection(row);
      } else if (ctrlFlag && !shiftFlag) {
        this.$refs.mutipleTable.toggleRowSelection(row);
        row.checked = !row.checked;
        if (row.checked) {
          this.getIndexByRow(row);
        }
      }
    },
    // 变色样式监听
    tableRowStyle({ row }) {
      if (row.checked) {
        return { background: "skyblue" };
      } else if (!row.checked) {
        return { background: row.color };
      }
    },
  },
  components: {},
};
</script>

<style>
.mask {
  position: fixed;
  background: #409eff;
  opacity: 0.4;
  z-index: 999;
}

/deep/ div .red-cell {
  background: #f0f0f0;
}
/deep/ .el-table .warning-row {
  background: skyblue;
}

/deep/ .el-table .red-row {
  background: red;
}

::v-deep .el-table .el-table__cell {
  padding: 0;
}
/deep/ .el-table .success-row {
  background: #f0f9eb;
}

/deep/ .cell {
  user-select: none;
}
/deep/ .el-table tbody tr:hover > td {
  background-color: transparent !important;
}

.contextmenu {
  margin: 0;
  background: #fff;
  z-index: 3000;
  position: absolute;
  list-style-type: none;
  padding: 5px 0;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 400;
  color: #333;
  box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
  li {
    margin: 0;
    padding: 7px 16px;
    cursor: pointer;
    &:hover {
      background: #eee;
    }
  }
}
</style>
